public class Test {
    public static void main(String[] args) throws Exception {
        DrinkMaker maker = new CoffeeMaker();
        maker.make(); // 骨架相同，步骤不同

        System.out.println("----- 换茶 -----");
        maker = new TeaMaker();
        maker.make();
    }
}
// 定义一个操作中的算法的骨架，而将一些步骤延迟到子类中，使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

// 模板方法（Template Method）是一个比较简单的模式。
// 它的主要思想是，定义一个操作的一系列步骤，对于某些暂时确定不下来的步骤，就留给子类去实现好了，
// 这样不同的子类就可以定义出不同的步骤
/* ---------- 抽象模板 ---------- */
abstract class DrinkMaker {
    // 模板方法：骨架固定，final 不让子类改
    final void make() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }

    /* === 通用步骤 === */
    private void boilWater() {
        System.out.println("煮水");
    }

    private void pourInCup() {
        System.out.println("倒入杯子");
    }

    /* === 可变步骤：子类填空 === */
    abstract void brew();

    abstract void addCondiments();
}

/* ---------- 具体模板 ---------- */
class CoffeeMaker extends DrinkMaker {
    void brew() {
        System.out.println("冲泡咖啡粉");
    }

    void addCondiments() {
        System.out.println("加糖和牛奶");
    }
}

class TeaMaker extends DrinkMaker {
    void brew() {
        System.out.println("浸泡茶叶");
    }

    void addCondiments() {
        System.out.println("加柠檬");
    }
}